import React from 'react';
import { mat, ones } from '@josh-brown/vector';
import _ from 'lodash';
import moment from 'moment';
import getCharts from './getCharts';
import { getColumns } from './columns';

const CATEGORYS = {
  contract: {
    category: '合约汇总(MWh)',
    icon: 'icon-juxingtuli',
    color: '#204A64',
    t: 'total',
  },
  price: {
    category: '合约电价(元/MWh)',
    icon: '#',
    t: 'total',
  },
  remaining: {
    category: '剩余仓位',
    icon: 'icon-shengyucangwei',
    t: 'total',
  },
  capacity: {
    category: '产能预测',
    icon: 'icon-quxiantuli',
    t: 'total',
  },
};

export default ({ buttonPermissions, pageType, form, result, handleEdit, counterPartyList }) => {
  const [charts, setCharts] = React.useState(null);
  const [columns, setColumns] = React.useState([]); // 表格列
  const [tableData, setTableData] = React.useState([]); // 表格数据
  const [total, setTotal] = React.useState(0); // 时间列 总数量
  let [count, setCount] = React.useState({});

  React.useEffect(() => {
    if (!form) return;
    const _cols = getColumns({ buttonPermissions, form, handleEdit, counterPartyList });
    setColumns(_cols);
    setTotal(_cols?.length ? _cols.length - 2 : 0);
    count = {
      day: moment(form.endDate).diff(moment(form.startDate), 'days'),
      month: moment(form.endDate).diff(moment(form.startDate), 'months'),
    };
    setCount(count);
  }, [form?.startDate, form?.endDate, form?.latitude, form?.radixType, counterPartyList]);

  React.useEffect(() => {
    initData();
  }, [JSON.stringify(result), JSON.stringify(columns), form?.latitude, form?.radixType]);

  // 列加和
  const getColsSum = (arr, t) => {
    if (!arr?.length) {
      let dataLen;
      const days = moment(form.endDate).diff(moment(form.startDate), 'days') + 1;
      const months = moment(form.endDate).diff(moment(form.startDate), 'months') + 1;
      if (t === '96') dataLen = 96 * days;
      else if (t === '24') dataLen = 24 * days;
      else if (t === 'day') dataLen = days;
      else if (t === 'month') dataLen = months;
      else if (t === 'stack96') dataLen = 96;
      else if (t === 'stack24') dataLen = 24;
      return Array.from({ length: dataLen }, () => null);
    }
    return mat(arr).transpose().apply(ones(arr.length)).toArray();
  };
  // 分组加和
  const chunkSum = (arr, n) => _.chunk(arr, n).map((item) => _.sum(item));
  // 除
  const divideNum = (a, b) => (!a || !b ? null : a / b);
  /**
   * 数据聚合
   * @param {object} obj 每日96点数据
   * @param {string} latitude
   */
  const polyData = (obj, latitude) => {
    let values = Object.values(obj || {});
    let vflat = values.flat();
    switch (latitude) {
      case '96':
        // 96点连续
        return vflat;
      case 'stack96':
        // 96点叠加
        return getColsSum(values, latitude);
      case '24':
        // 24小时连续
        return chunkSum(vflat, 4);
      case 'stack24':
        // 24小时叠加
        const sums = getColsSum(values, latitude);
        return chunkSum(sums, 4);
      case 'day':
        // 日 加和
        return chunkSum(vflat, 96);
      case 'month':
        // 月 加和
        let monthMap = {};
        Object.entries(obj || {}).map(([day, list]) => {
          const mm = moment(day).format('MM');
          if (typeof monthMap[mm] === 'undefined') monthMap[mm] = 0;
          monthMap[mm] += _.sum(list);
        });
        return Object.values(monthMap);
      default:
        return [];
    }
  };

  const initData = () => {
    // 生成表格、ECharts数据
    if (!result || !columns.length) return;
    const times = columns.slice(2).map((x) => x.code); // 时间列
    const { latitude, radixType } = form;
    let allMap = { capacity: [], income: [], quantity: [], remaining: [] }; // 总计
    let childList = []; // 子页面按合约展示
    // 主页面按场站（所有合约聚合）展示
    const list = result.map((item) => {
      const { baseContract, contracts, capacity, remaining, stationId, stationName } = item;
      let conList = [...contracts]; // 所有合约
      let allConCapacity = polyData(capacity, latitude); // 产能预测
      let allConRemaining = polyData(remaining, latitude); // 剩余仓位
      if (!!baseContract) {
        conList.unshift(baseContract);
        if (radixType === '2') {
          // 合约中含基数，剩余仓位 -= 基数合约电量
          const baseQuantity = polyData(baseContract?.quantity, latitude);
          allConRemaining = allConRemaining.map((n, i) => {
            if (!baseQuantity[i]) return n;
            return n - baseQuantity[i];
          });
        }
      }
      allMap.capacity.push(allConCapacity);
      allMap.remaining.push(allConRemaining);
      /** 遍历合约 */
      // 合约电价 = 合约总收入 / 合约总电量
      let matIncome = []; // 合约收入 = price * quantity
      let matQuantity = []; // 合约电量 = quantity
      conList.map((item) => {
        let incomeObj = {};
        Object.entries(item.price).map(([k, v]) => {
          incomeObj[k] = v.map((_price, i) => _price * item.quantity[k][i]);
        });
        // 单条合约
        const conIncome = polyData(incomeObj, latitude); // 收入
        const conQuantity = polyData(item.quantity, latitude); // 电量
        if (pageType === 'child') {
          const conPrice = conIncome.map((x, i) => divideNum(x, conQuantity[i])); // 电价
          let childTemp = {
            id: item.id + '',
            category: item.contractName,
            total: _.sum(conQuantity),
            calculate: item.calculate,
            contractType: item.contractType,
            contractId: item.contractId,
            counterpartyId: item.counterpartyId,
            t: item.contractType === 'baseContract' ? '' : 'edit', // 基础合约不可编辑
            children: [
              {
                id: `${item.id}_a`,
                category: '合约电价',
                total: divideNum(_.sum(conIncome), _.sum(conQuantity)),
              },
            ],
          };
          times.map((code, i) => {
            childTemp[code] = conQuantity[i];
            childTemp['startDate'] = item?.startDate || null;
            childTemp['endDate'] = item?.endDate || null;
            childTemp['contractName'] = item?.contractName || '';
            childTemp['counterpartyId'] = item?.counterpartyId || null;
            childTemp.children[0][code] = conPrice[i];
          });
          childList.push(childTemp);
        }
        // 不加算 已隐藏的合约
        if (item.calculate === '0') return;
        // 不加算 非合约中含基数时 的基础合约
        if (radixType === '1' && item.contractType === 'baseContract') return;
        matIncome.push(conIncome); // 合约收入聚合
        matQuantity.push(conQuantity); // 合约电量聚合
      });
      /** 计算汇总 */
      const allConIncome = getColsSum(matIncome, latitude); // 合约总收入(分时段)
      const allConQuantity = getColsSum(matQuantity, latitude); // 合约总电量(分时段)
      allMap.income.push(allConIncome);
      allMap.quantity.push(allConQuantity);
      const allConPrice = allConIncome.map((x, i) => divideNum(x, allConQuantity[i]));
      if (pageType === 'main') {
        let temp = {
          id: stationId,
          category: stationName,
          total: _.sum(allConQuantity),
          t: 'jump',
          children: [
            {
              category: '合约电价',
              id: `${stationId}_a`,
              total: divideNum(_.sum(allConIncome), _.sum(allConQuantity)),
            },
            {
              category: '产能预测',
              id: `${stationId}_b`,
              total: _.sum(allConCapacity),
            },
            {
              category: '剩余仓位',
              id: `${stationId}_c`,
              total: _.sum(allConRemaining),
            },
          ],
        };
        times.map((code, i) => {
          temp[code] = allConQuantity[i];
          temp.children[0][code] = allConPrice[i];
          temp.children[1][code] = allConCapacity[i];
          temp.children[2][code] = allConRemaining[i];
        });
        return temp;
      }
    });
    // 计算总计
    const sum_capacity = getColsSum(allMap.capacity, latitude);
    const sum_remaining = getColsSum(allMap.remaining, latitude);
    const sum_income = getColsSum(allMap.income, latitude);
    const sum_quantity = getColsSum(allMap.quantity, latitude);
    const sum_price = sum_income.map((x, i) => divideNum(x, sum_quantity[i]));
    const totals = [
      {
        id: 'total_quantity',
        ...CATEGORYS['contract'],
        total: _.sum(sum_quantity),
      },
      {
        id: 'total_price',
        ...CATEGORYS['price'],
        total: divideNum(_.sum(sum_income), _.sum(sum_quantity)),
      },
      {
        id: 'total_remaining',
        ...CATEGORYS['remaining'],
        total: _.sum(sum_remaining),
      },
      {
        id: 'total_capacity',
        ...CATEGORYS['capacity'],
        total: _.sum(sum_capacity),
      },
    ];
    let chartData = [];
    times.map((code, i) => {
      chartData.push({
        code,
        quantity: sum_quantity[i],
        remaining: sum_remaining[i],
        capacity: sum_capacity[i],
      });
      totals[0][code] = sum_quantity[i];
      totals[1][code] = sum_price[i];
      totals[2][code] = sum_remaining[i];
      totals[3][code] = sum_capacity[i];
    });
    const _charts = getCharts(chartData, latitude);
    let _table;
    if (pageType === 'main') {
      _table = [...totals, ...list];
    } else if (pageType === 'child') {
      _table = [...totals, ...childList];
    }
    setCharts(_charts);
    setTableData(_table);
  };

  return {
    charts,
    columns,
    tableData,
    total,
  };
};
